package com.geoai.featgeoaivideo.mvi.vm

import android.util.Log
import com.geoai.basiclib.base.mvi.BaseEISViewModel
import com.geoai.basiclib.ext.SP
import com.geoai.basiclib.ext.putString
import com.geoai.featgeoaivideo.mvi.eis.GeoaiVideoEffect
import com.geoai.featgeoaivideo.mvi.eis.GeoaiVideoIntent
import com.geoai.featgeoaivideo.mvi.eis.GeoaiVideoState
import com.geoai.modservice.di.eventbus.CameraLinesStyle
import com.geoai.modservice.di.eventbus.OnMapTouchEvent
import com.geoai.modservice.di.sp.FpvControlConstants
import com.geoai.video.VideoFeederView5
import com.geoai.video.VideoFeederView5.PlayNode
import com.geoai.video.YFV5Params
import com.zkyt.lib_msdk_ext.ProductManagerExt
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.rxkotlin.addTo
import kotlinx.coroutines.delay
import org.greenrobot.eventbus.EventBus

/**
 * @Author      : Ronny
 * @Email       : Ronny_xie@hotmail.com
 * @Date        : on 2024-04-11 11:14.
 * @Description :
 */
class GeoaiVideoViewModel: BaseEISViewModel<GeoaiVideoEffect, GeoaiVideoIntent, GeoaiVideoState>() {

    var fpvTouchPosition: Pair<Int, Int> = Pair(0, 0)

    private var cameraSource: PlayNode

    init {
        cameraSource = updateFpvSource(PlayNode.valueOf(SP().getString(FpvControlConstants.FPV_SOURCE_TYPE, PlayNode.MAIN_CAM.name)!!))

        launchOnUI {

            delay(1000)

            CameraLinesStyle.valueOf(SP().getString(FpvControlConstants.CAMERA_LINE_STYLE, CameraLinesStyle.NONE.name)!!).let {
                sendEffect {
                    GeoaiVideoEffect.UpdateCameraLineStyle(it)
                }
            }

            registerProductConnectedStatus { isConnected ->
                if (isConnected) {
                    sendUiIntent(GeoaiVideoIntent.ObtainPlayParam(true))
                    sendEffect { GeoaiVideoEffect.UpdateFpvSource(cameraSource.name) }
                }
            }
        }
    }

    override fun initUiState(): GeoaiVideoState = GeoaiVideoState.MiniFpv

    override fun handleIntent(intent: GeoaiVideoIntent) {
        when (intent) {
            is GeoaiVideoIntent.ObtainPlayParam -> buildPlayerParam(intent.autoPlay)
            GeoaiVideoIntent.OnFpvTouchEvent -> onFpvTouchEvent()
            GeoaiVideoIntent.ToggleFpvSource -> toggleFpvSource()
            is GeoaiVideoIntent.SaveCameraLineStyle -> { SP().putString(FpvControlConstants.CAMERA_LINE_STYLE, intent.style.name) }
        }
    }

    private fun toggleFpvSource() {
        val targetSource = when (cameraSource) {
            PlayNode.MAIN_CAM -> PlayNode.FPV_CAM
            else -> PlayNode.MAIN_CAM
        }
        cameraSource = updateFpvSource(targetSource)
        sendUiIntent(GeoaiVideoIntent.ObtainPlayParam(true))
        sendEffect { GeoaiVideoEffect.UpdateFpvSource(cameraSource.name) }
    }

    private fun updateFpvSource(source: PlayNode): PlayNode {
        SP().putString(FpvControlConstants.FPV_SOURCE_TYPE, source.name)
        return source
    }

    private fun buildPlayerParam(isAutoPlay: Boolean) {
        val yfV5Params = YFV5Params.Builder()
            .setPlayNode(cameraSource)
            .setVideoDecodeMode(VideoFeederView5.DecodeMode.H265)
            .setVideoCodecMode(VideoFeederView5.CodecMode.HARDWARE)
            .build()

        if (isAutoPlay) sendEffect { GeoaiVideoEffect.StartPlay(yfV5Params) }
    }

    private fun onFpvTouchEvent() {
        if (uiStateFlow.value == GeoaiVideoState.BigFpv) return

        EventBus.getDefault().post(OnMapTouchEvent())
    }

    private fun registerProductConnectedStatus(successBlock: (e: Boolean) -> Unit) {
        ProductManagerExt.cameraManagerExt.getConnectedObservable()
            .distinctUntilChanged()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                successBlock.invoke(it)
            }.addTo(compositeDisposable)
    }
}